﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace ColorClusteringSOM
{
   
[Serializable]
    public class Neuron
    {
        protected int inputsCount = 0;
        protected double outputValue = 0;
        protected double[] weights = null;
        protected bool winner = false;

    //cislo ktere urcuje neuron v siti 1,2,3 atd je to potreba pro fidlera
        protected int numberOfNeuron = -1;

        private Color color = Color.Black;

        private int x = -1;
        private int y = -1;

        private int attack = 0;//int.MaxValue;

        private bool noEntry = false;

        /// <summary>
        /// Utok
        /// </summary>
        public void Attack()
        {
            //this.attack = 0;
            attack++;
            noEntry = true;
        }

        public bool NoEntry
        {
            get { return this.noEntry; }
        }



        /// <summary>
        /// Nebyl utok
        /// </summary>
        public void NOAttack()
        {
            attack--;
            noEntry = true;
        }

        #region Properties

        public int AttackCounter()
        {
            return this.attack;
        }

        public int NeuronType
        {
            get {
                if (attack == int.MaxValue)
                {
                    return attack;
                }
                if (attack > 0)
                {
                    return 1;
                }
                
                return 0;
            
            }
        }

        public int NumberOfNeuron
        {
            set { this.numberOfNeuron = value; }
            get { return numberOfNeuron; }
        }

        public Color RGBColor
        {
            get
            {

                int R = (int)(weights[0] * 255);
                int G = (int)(weights[1] * 255);
                int B = (int)(weights[2] * 255);
                return Color.FromArgb(R, G, B);
            }
            set { this.color = value; }
        }

        public int X { set { this.x = value; } get { return this.x; } }
        public int Y { set { this.y = value; } get { return this.y; } }

        public bool Winner { set { this.winner = value; } get { return this.winner; } }

        public double[] Weights
        {
            set { this.weights = value; }
            get { return this.weights; }
        }

        public double OutputValue
        {
            get { return this.outputValue; }
        }

        #endregion
        protected static Random rnd = new Random((int)DateTime.Now.Ticks);

        public Neuron(int inputsCount)
        {
            this.inputsCount = inputsCount;
            weights = new double[inputsCount];
        }

        public Neuron()
        {
            
        }
      
        /// <summary>
        /// vytvoreni nahodnych vah 0 - 1
        /// </summary>
        public void RandomizeWeights()
        {

            double r, rr;
            //for (int i = 0; i < weights.Length; i++)
            //{
            for (int j = 0; j < inputsCount; j++)
            {
                r = rnd.NextDouble();
                rr = rnd.NextDouble();

                this.weights[j] = (rr * r) * 0.9; //original
                //this.weights[j] = r ;
                // Console.WriteLine(r);

            }
            NormalizationWeights();

            //}
        }

        private void NormalizationWeights()
        {
            double normalizer = 0;

            double pom = 0;

            for (int j = 0; j < inputsCount; j++)
            {
                pom += (this.weights[j] * this.weights[j]);
            }

            pom = Math.Sqrt(pom);
            normalizer = 1 / pom;

            for (int j = 0; j < inputsCount; j++)
            {
               this.weights[j] = this.weights[j] * normalizer;
            }


        }


        /*
         The weights vector x = ( 1.2, -2.3, 3.4, -4.55, 5.6 ) is normalized as follows:

    c = 1.0 / sqrt( 1.22 + ( -2.3 )2 + 3.42 + ( -4.55 )2 + 5.62 ) = 0.1192

    x = ( 1.2* 0.1192, (-2.3)*0.1192, 3.4*0.1192, (-4.55)*0.1192, 5.6*0.1192 )
     
         */

        public override string ToString()
        {
            //String s = "winner?=" +this.winner + " ,X=" + this.X + " Y=" + this.Y + "[";
            //for (int i = 0; i < this.Weights.Length; i++)
            //{
            //    s += Weights[i] + ",";
            //}
            ////Console.WriteLine(s);
            //return (s + "]");


            String s = "NO:"+this.NumberOfNeuron +" ENTRY?:"+ this.noEntry +" attacks:"+ this.attack + " ["+this.X+"," + this.Y+"]";
            return s;

        }

    }

}
